package com.yanqu.road.server.manger.config;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.dao.impl.player.UserVehicleBoneDaoImpl;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.vehicle.*;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.enums.eVehicleSkillType;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.logic.bussiness.config.VehicleBussiness;
import com.yanqu.road.logic.bussiness.player.UserVehicleBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.HouseModule;
import com.yanqu.road.server.gameplayer.module.vehicle.VehicleModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class VehicleMgr extends TempMgr {

	private static Map<Integer, VehicleInfo> vehicleInfoMap;

	private static Map<Integer, VehicleBreak> vehicleBreakMap;

	private static Map<Integer, Map<Integer, VehicleStudy>> vehicleStudyMap;

	private static Map<Integer, VehicleSkillInfo> vehicleSkillInfoMap;

	private static Map<Integer, VehicleComb> vehicleCombMap;

	private static RandomHelper threadSafeRandom = new RandomHelper();

	public static final int ONCE_SEND_VEHICLE_COUNT = 200;

	public static void bindVehicleToPatrons(int activityId, long userId, int patronsId) {
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		if (player != null) {
			UserVehicle vehicle = player.getModule(VehicleModule.class).getUserVehicleByPatrons(patronsId);
			if (vehicle != null) {
				player.getModule(VehicleModule.class).addPatronsBindData(activityId,patronsId,vehicle.getVehicleUid());
			}
		}else {
			Map<String, UserVehicle> vehicleMap = UserVehicleBussiness.getUserVehicleMap(userId);
			String vehicleId = null;
			for (UserVehicle vehicle : vehicleMap.values()) {
				if (vehicle.getPatronsId() == patronsId && !vehicle.isDelete()) {
					vehicleId = vehicle.getVehicleUid();
				}
			}
			if (vehicleId != null) {
				Map<String, PatronsVehicleBindingData> dataMap = UserVehicleBussiness.getPatronsVehicleBindingData(userId);
				PatronsVehicleBindingData data = dataMap.get(vehicleId);
				if (data == null) {
					data = new PatronsVehicleBindingData();
					data.setVehicleId(vehicleId);
					data.setUserId(userId);
					data.setInsertOption();
				}
				if (data.getActivityIdList().contains(activityId) && data.getPatronsId() == patronsId) {
					return;
				}
				data.setPatronsId(patronsId);
				data.addActivityId(activityId);
				data.setLastUpdateTime(System.currentTimeMillis());

				if (data.isInsertOption()) {
					UserVehicleBussiness.addPatronsVehicleBindingData(data);
				}else{
					UserVehicleBussiness.aupdatePatronsVehicleBindingData(data);
				}
			}
		}
	}

	public static Map<String, UserVehicle> getUserVehicleMap(long userId) {
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		if(null != player){
			return player.getModule(VehicleModule.class).getUserVehicleMap();
		}else {
			return UserVehicleBussiness.getUserVehicleMap(userId);
		}
	}

	public static Map<Long,Map<String, UserVehicle>> getSomeUserVehicleMap(List<Long> userIdList) {
		return UserVehicleBussiness.getSomeUserVehicleMap(userIdList);
	}

	@Override
	public boolean init() throws Exception {
		return reload();
	}

	@Override
	public boolean stop() {
		return false;
	}

	@Override
	public boolean save() {
		return false;
	}

	@Override
	public boolean reloadConfig() {
		vehicleInfoMap = VehicleBussiness.getVehicleInfoMap();
		vehicleBreakMap = VehicleBussiness.getVehicleBreakMap();
		vehicleStudyMap = VehicleBussiness.getVehicleStudyMap();
		vehicleSkillInfoMap = VehicleBussiness.getVehicleSkillInfoMap();
		vehicleCombMap = VehicleBussiness.getVehicleCombMap();
		initVehicleComb();

		return true;
	}

	@Override
	public boolean reloadData() throws Exception {
		return true;
	}

	/**
	 * 初始化门客组合信息
	 */
	private void initVehicleComb(){
		for(VehicleComb vehicleComb : vehicleCombMap.values()){
			List<Integer> vehicleIdList = new ArrayList<>();
			for(VehicleInfo vehicleInfo : vehicleInfoMap.values()){
				if(vehicleComb.getId() == vehicleInfo.getCombId()){
					if(!vehicleIdList.contains(vehicleInfo.getId())){
						vehicleIdList.add(vehicleInfo.getId());
					}
				}
			}
			vehicleComb.setVehicleIdList(vehicleIdList);
		}
	}

	//本来获取组合的第一个技能的对应所有珍兽是直接用VehicleComb的vehicleIdList，现在有会把多个组合珍兽一起来升级第一个技能
	public static List<Integer> getCombCombVehicleList(int combId){
		List<Integer> combVehicleIdList = new ArrayList<>();
		if(!vehicleCombMap.containsKey(combId)){
			return combVehicleIdList;
		}
		VehicleComb vehicleComb = vehicleCombMap.get(combId);
		combVehicleIdList.addAll(vehicleComb.getVehicleIdList());
		for(Integer combCombId : vehicleComb.getCombList()){
			if(vehicleCombMap.containsKey(combCombId)){
				combVehicleIdList.addAll(vehicleCombMap.get(combCombId).getVehicleIdList());
			}
		}
		return combVehicleIdList;
	}


	/**
	 * 组合是否解锁,必须全部都有
	 */
	public static boolean isUnlockVehicleComb(int vehicleId, Map<String, UserVehicle> userVehicleMap){
		VehicleInfo vehicleInfo = getVehicleInfo(vehicleId);
		if(null == vehicleInfo){
			return false;
		}
		if(vehicleInfo.getCombId() <= 0){
			return false;
		}
		if(null == userVehicleMap){
			return false;
		}
		VehicleComb vehicleComb = getVehicleComb(vehicleInfo.getCombId());
		if(null == vehicleComb){
			return false;
		}
		if(null == vehicleComb.getVehicleIdList() || vehicleComb.getVehicleIdList().size() <= 0){
			return false;
		}
		for(int templateId : vehicleComb.getVehicleIdList()){
			if(!isInUserVehicleMap(templateId,userVehicleMap)){
				return false;
			}
		}
		return true;
	}

	/**
	 * 组合加成
	 */
	public static int getCombAddition(UserVehicle userVehicle){
		int addition = 0;
		if(null == userVehicle ){
			return addition;
		}
		VehicleInfo vehicleInfo = getVehicleInfo(userVehicle.getTemplateId());
		if(null == vehicleInfo){
			return addition;
		}
		VehicleComb vehicleComb = getVehicleComb(vehicleInfo.getCombId());
		if(null == vehicleComb){
			return addition;
		}
		SkillInfo skillInfo;
		UserVehicleOtherSkill combSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), vehicleComb.getCombSkillId());
		if(null != combSkill){
			skillInfo = SkillMgr.getSkillInfo(combSkill.getSkillId());
			if (eSkillType.VehicleCombSkill.getValue() == skillInfo.getType()) {
				addition += SkillMgr.getSkillAddition(skillInfo, combSkill.getSkillLv());
			}
		}
		UserVehicleOtherSkill vehicleSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), vehicleComb.getSkillId(userVehicle.getPatronsId()));
		if(null != vehicleSkill) {
			skillInfo = SkillMgr.getSkillInfo(vehicleSkill.getSkillId());
			if (eSkillType.VehicleCombSkill.getValue() == skillInfo.getType()) {
				addition += SkillMgr.getSkillAddition(skillInfo, vehicleSkill.getSkillLv());
			}
		}
		List<Integer> selfSkillIdList = vehicleComb.getVehicleSelfSkillMap().getOrDefault(userVehicle.getTemplateId(), new ArrayList<>());
		for (Integer skillId : selfSkillIdList) {
			UserVehicleOtherSkill selfCombSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), skillId);
			if(null != selfCombSkill){
				skillInfo = SkillMgr.getSkillInfo(selfCombSkill.getSkillId());
				if (eSkillType.VehicleCombSkill.getValue() == skillInfo.getType()) {
					addition += SkillMgr.getSkillAddition(skillInfo, selfCombSkill.getSkillLv());
				}
			}
		}

		return addition;
	}

	//某种类型的珍兽是否在用户身上存在
	public static boolean isInUserVehicleMap(int templateId,Map<String,UserVehicle> userVehicleMap){
		for(UserVehicle userVehicle : userVehicleMap.values()){
			if(userVehicle.getTemplateId() == templateId){
				return true;
			}
		}
		return false;
	}

	public static VehicleComb getVehicleComb(int combId){
		return vehicleCombMap.get(combId);
	}

	public static Map<Integer, VehicleInfo> getVehicleInfoMap() {
		return vehicleInfoMap;
	}

	/**
	 * 返回坐骑资质
	 */
	public static long getVehicleQualification(int templateId, int level) {
		VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(templateId);
		long qualification = 0;
		if(null != vehicleInfo){
			qualification = vehicleInfo.getQualification();
			qualification = qualification + (vehicleInfo.getAddQualification() * (level -1));
		}
		if(qualification < 0){
			qualification = 0;
		}
		return qualification;
	}

	/**
	 * 获取光环技能
	 * @param userVehicle
	 * @return
	 */
	public static JSONArray getOtherSkillArray(UserVehicle userVehicle){
		JSONArray otherSkillArray = new JSONArray();
		for (UserVehicleOtherSkill vehicleOtherSkill : new ArrayList<>(userVehicle.getOtherSkillList())) {
			JSONObject otherSkillObject = new JSONObject();
			otherSkillObject.put("skillId", vehicleOtherSkill.getSkillId());
			otherSkillObject.put("skillType", vehicleOtherSkill.getSkillType());
			otherSkillObject.put("skillLv", vehicleOtherSkill.getSkillLv());
			otherSkillArray.add(otherSkillObject);
		}
		return otherSkillArray;
	}

	/**
	 * 随机技能
	 */
	public static VehicleSkillInfo getRandomSkill(boolean isCustom, int occupation){
		VehicleSkillInfo resultSkill = new VehicleSkillInfo();
		int skillType = getRandomSkillType(occupation);
		resultSkill.setSkillType(skillType);
		VehicleSkillInfo vehicleSkillInfo = getVehicleSkillInfo(skillType);
		if(null == vehicleSkillInfo){
			return resultSkill;
		}
		int skillValue = getRandomSkillValue(isCustom);
		resultSkill.setValue(skillValue);
		return resultSkill;
	}

	public static boolean isUserVehicleExist(UserVehicle userVehicle) {
		if (null == userVehicle) {
			return false;
		}
		return !userVehicle.isDelete();
	}

	private static int getRandomSkillValue(boolean isCustom){
		List<Integer> weightList;
		if(isCustom){//是否定制
			weightList = ConfigMgr.getVehicleSkillCustomModifyParamList();
		}else {
			weightList = ConfigMgr.getVehicleSkillNormalModifyParamList();
		}
		int sumWeight = 0;
		for(int weight : weightList){
			sumWeight += weight;
		}
		int randomValue = threadSafeRandom.next(0, sumWeight);
		int tempWeight = 0;
		for(int i = 0; i < weightList.size(); i++){
			int weight = weightList.get(i);
			tempWeight += weight;
			if(tempWeight > randomValue){
				return i + 1;
			}
		}
		return 0;
	}

	private static int getRandomSkillType(int occupation){
		if(occupation > 0){
			int randomValue = threadSafeRandom.next(0, 1000);
			if(ConfigMgr.getVehicleSkillModifyParam2() > randomValue){
				return occupation;
			}
		}
		return threadSafeRandom.next(1, vehicleSkillInfoMap.size() + 1);
	}

	public static VehicleInfo getVehicleInfo(int templateId) {
		return vehicleInfoMap.get(templateId);
	}

	public static VehicleBreak getVehicleBreak(int breakLv){
		return vehicleBreakMap.get(breakLv);
	}

	public static VehicleStudy getVehicleStudy(int type, int studyLv){
		if(vehicleStudyMap.containsKey(type)) {
			return vehicleStudyMap.get(type).get(studyLv);
		}
		return null;
	}

	public static Map<Integer, VehicleStudy> getVehicleStudy(int type){
		if(vehicleStudyMap.containsKey(type)){
			return vehicleStudyMap.get(type);
		}
		return new HashMap<>();
	}

	public static VehicleSkillInfo getVehicleSkillInfo(int skillType){
		return vehicleSkillInfoMap.get(skillType);
	}

	public static Property getVehicleUpgradeConsume(VehicleInfo vehicleInfo){
		return new Property(GameConfig.VEHICLE_UPGRADE_CONSUME_ITEM_ID, BigInteger.valueOf(vehicleInfo.getUpgradeConsumeCount()));
	}

	public static Property getVehicleTotalUpgradeConsume(UserVehicle userVehicle){
		VehicleInfo vehicleInfo = getVehicleInfo(userVehicle.getTemplateId());
		long count = vehicleInfo.getUpgradeConsumeCount() * (userVehicle.getLevel() - 1);
		return new Property(GameConfig.VEHICLE_UPGRADE_CONSUME_ITEM_ID, BigInteger.valueOf(count));
	}

	public static int getVehicleMaxLevel(GamePlayer player, int maxLevel){
		int skillAddition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.VehicleLevel.getValue(), 0);
		//钱庄技能加成等级上限
		int houseBankAddition = player.getModule(HouseModule.class).getIdentitySkillAddition(eSkillType.VehicleLevel.getValue(), 0);
		// 门客也要加
		int patronsAddition = player.getModule(PatronsModule.class).getSkillAddition(eSkillType.VehicleLevel.getValue(), 0);
		// 组合珍兽进阶技能
		int vehicleAdvanceAddition = player.getModule(VehicleModule.class).getSkillAddition(eSkillType.VehicleLevel.getValue(), 0);
		// 藏宝系统
		int curioSkillAddition = (int)CurioMgr.getSkillAdditionBySkillType(eSkillType.VehicleLevelLimitAddSkill.getValue(), player, 0);
		return maxLevel + skillAddition + houseBankAddition + patronsAddition + vehicleAdvanceAddition + curioSkillAddition;
	}

	public static int getVehicleMaxStudyTimes(GamePlayer player){
		int skillAddition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.VehicleStudyLv.getValue(), 0);
		int houseAddition = player.getModule(HouseModule.class).getIdentitySkillAddition(eSkillType.VehicleStudyLv.getValue(), 0);
		int curioAddition = (int)CurioMgr.getSkillAdditionBySkillType(eSkillType.VehicleAwakenLimitAddSkill.getValue(), player, 0);
		return GameConfig.VEHICLE_MAX_STUDY_TIMES + skillAddition + houseAddition + curioAddition;
	}

	public static int getVehicleEquipCost(int buyTimes){
		int ingots = GameConfig.VEHICLE_EQUIP_BASE_COST + GameConfig.VEHICLE_EQUIP_ADD_COST * buyTimes;
		if(ingots < 0){
			ingots = 0;
		}
		if(ingots > GameConfig.VEHICLE_EQUIP_MAX_COST){
			ingots = GameConfig.VEHICLE_EQUIP_MAX_COST;
		}
		return ingots;
	}

	public static BigInteger getModifySkillCost(int times){
		BigDecimal value1 = BigDecimal.valueOf((double) ConfigMgr.getVehicleSkillModifySilverCostParam1() / 1000);
		BigDecimal value2 = BigDecimal.valueOf(Math.pow(ConfigMgr.getVehicleSkillModifySilverCostParam2() + times, 4));
		BigDecimal value3 = BigDecimal.valueOf((double) ConfigMgr.getVehicleSkillModifySilverCostParam3() / 1000);
		BigDecimal value4 = BigDecimal.valueOf(Math.pow((double)ConfigMgr.getVehicleSkillModifySilverCostParam4() /1000, times - 1));
		return value1.multiply(value2).add(value3.multiply(value4)).setScale(0, BigDecimal.ROUND_UP).toBigInteger();
	}

	public static int getVehicleSkillValidCount(UserVehicle userVehicle) {
		if (null == userVehicle) {
			return 0;
		}
		if(userVehicle.getPatronsId() <= 0){
			return 0;
		}
		PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userVehicle.getPatronsId());
		Map<Integer, UserVehicleSkill> skillMap = userVehicle.getSkillMapEffect();
		int count = 0;
		if(null != skillMap){
			for(UserVehicleSkill skill : skillMap.values()){
				if(skill.getSkillType() == patronsInfo.getOccupation()){
					count++;
				}
			}
		}
		return count;
	}

	public static int getPatronsOccupationAddition(UserPatrons userPatrons, UserVehicle userVehicle){
		int addition = 0;
		if(null == userPatrons || null == userVehicle){
			return addition;
		}
		PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
		if(null == patronsInfo){
			return addition;
		}
		for(UserVehicleSkill vehicleSkill : userVehicle.getSkillMapEffect().values()){
			if(vehicleSkill.getSkillType() == patronsInfo.getOccupation()){
				addition += vehicleSkill.getValue();
			}
		}
		return addition;
	}

	/**
	 * 判断是否允许
	 * @return
	 * @param player
	 */
/*	public static boolean canDismountVehicle(GamePlayer player) {
		// 判断花石纲活动
		if (SystemOpenMgr.systemOpen(player, eSystemId.HuaShiGang.getValue()) && ActivityMgr.activityInTime(HuaShiGangMgr.getActivityInfo())) {
			//活动期间每日 10点 - 22点 不能更换珍兽
			if (HuaShiGangMgr.inOperateTime(HuaShiGangMgr.getActivityInfo())) {
				return false;
			}
		}
		if (SystemOpenMgr.systemOpen(player, eSystemId.StrongholdActivity.getValue()) && !StrongholdWarMgr.canDismountVahicle(player)) {
			return false;
		}
		if (SystemOpenMgr.systemOpen(player, eSystemId.GhostActivity.getValue()) && GhostMgr.inOpenTime()) {
			return false;
		}
		return true;
	}*/

	/**
	 * 是否是可排行的珍兽类型
	 */
	public static boolean canJoinRank(int templateId) {
		VehicleInfo vehicleInfo = vehicleInfoMap.get(templateId);
		if (vehicleInfo == null) {
			return false;
		}
		if (vehicleInfo.getStudyTypeList().size() == 1 && vehicleInfo.getStudyTypeList().get(0) == 0) {
			return false;
		}
		return true;
	}

}
